
The Express framework lets you define routes, specifications of what to do when an HTTP request
matching a certain pattern arrives. The matching specification is regular expression (regex) based and is
very flexible, like most other web application frameworks. The what‑to‑do part is just a function that is
given the parsed HTTP request.
Express parses the request URL, headers, and parameters for you. On the response side, it has, as expected,
all functionality required by web applications. This includes determining response codes, setting cookies,
sending custom headers, etc. Further, you can write Express middleware, custom pieces of code that can be
inserted in any request/response processing path to achieve common functionality such as logging,
authentication, etc.
Express does not have a template engine built in, but it supports any template engine of your choice such as
pug, mustache, etc. But, for an SPA, you will not need to use a server‑side template engine. This is because
all dynamic content generation is done on the client, and the web server only serves static files and data via
API calls.
In summary, Express is a web server framework meant for Node.js. It’s not very different from many other
web server frameworks in terms of what you can achieve with it.
MONGODB
MongoDB is the database used in the MERN stack. It is a NoSQL document‑oriented database, with a flexible
schema and a JSON‑based query language. Not only do many modern companies (including Facebook and
Google) use MongoDB in production, but some older established companies such as SAP and Royal Bank of
Scotland have adopted MongoDB.
I’ll discuss a few things that MongoDB is (and is not) here.
NoSQL
NoSQL stands for “non‑relational,” no matter what the acronym expands to. It’s essentially not a
conventional database where you have tables with columns and rows and strict relationships among them.
I find that there are two attributes of NoSQL databases that differentiate them from the conventional.
The first is their ability to horizontally scale by distributing the load over multiple servers. They do this by
sacrificing an important (for some) aspect of the traditional databases: strong consistency. That is, the data
is not necessarily consistent for very brief amounts of time across replicas. For more information, read up
on the “CAP theorem” ( https://en.wikipedia.org/wiki/CAP_theorem ). But in reality, very few
applications require web‑scale, and this aspect of NoSQL databases comes into play very rarely.
The second, and according to me more important, aspect is that NoSQL databases are not necessarily
relational databases. You don’t have to think of your objects in terms of rows and columns of tables. The
difference between the representation in the application (objects) and on disk (rows in tables) is
sometimes called impedance mismatch. This is a term borrowed from electrical engineering, which means,
roughly, that we’re not talking the same language. Because of the impedance mismatch, we have to use a
layer that translates or maps between objects and relations. These layers are called Object Relational
Mapping (ORM) layers.
In MongoDB, instead, you can think of the persisted data just as you see them in your application code, that
is, as objects or documents. This helps you avoid the ORM layer and think of the persisted data as naturally
as you would in the application’s memory.
Document-Oriented
Compared to relational databases where data is stored in the form of relations, or tables, MongoDB is a
document‑oriented database. The unit of storage (comparable to a row) is a document, or an object, and
multiple documents are stored in collections (comparable to a table). Every document in a collection has a
unique identifier, using which it can be accessed. The identifier is indexed automatically.
Imagine the storage structure of an invoice, with the customer name, address, etc. and a list of items (lines)
in the invoice. If you had to store this in a relational database, you would use two tables, say, invoice and
invoice_lines, with the lines or items referring to the invoice via a foreign‑key relation. Not so in
MongoDB. You would store the entire invoice as a single document, fetch it, and update it in an atomic
operation. This applies not just to line items in an invoice. The document can be any kind of deeply nested
object.
Modern relational databases have started supporting one level of nesting by allowing array fields and JSON
fields, but it is not the same as a true document database. MongoDB has the ability to index on deeply
nested fields, which relational databases cannot do.
The downside is that the data is stored de‑normalized. This means that data is sometimes duplicated,
requiring more storage space. Also, things like renaming a master (catalog) entry name would mean
sweeping through the database and updating all occurrences of the duplicated data. But then, storage has
become relatively cheap these days, and renaming master entries are rare operations.
Schema-Less
Storing an object in a MongoDB database does not have to follow a prescribed schema. All documents in a
collection need not have the same set of fields.
This means that, especially during early stages of development, you don’t need to add/rename columns in
the schema. You can quickly add fields in your application code without having to worry about database
migration scripts. At first this may seem a boon, but in effect all it does is transfers the responsibility of data
sanity from the database to your application code. I find that in larger teams and more stable products, it is
better to have a strict or semi‑strict schema. Using Object Document Mapping libraries such as mongoose
(not covered in this book) alleviates this problem.
JavaScript Based
MongoDB’s language is JavaScript.
For relational databases, we had a query language called SQL. For MongoDB, the query language is based on
JSON. You create, search for, make changes, and delete documents by specifying the operation in a JSON
object. The query language is not English‑like (you don’t SELECT or say WHERE), and therefore much easier
to construct programmatically.